/*
	FileName : JT_C_SD_Structure.c
	Description :
		Manage the JT_C SD data structure.
	
	Created on 2017.11.06 by WFL.

	Revision History:

*/


/* Includes ------------------------------------------------------------------*/



#include "JT_C_SD_Structure.h"
#include "JT_C_REC_Wave.h"
#include "Misc_Fnx.h"		/// for CRC function
#include "JT_C_REC_Ver.h"
//-----------------------------Saving Position----------------------------------------------------

POS_INFO	PosInfo;

JTC_SD_STRUCTURE JTC_sdStr;

//-------------------


///Set copy position datas
void UpdatePosDataAfterUsbCopySuccess(POS_DATA *pos_data)
{
	pos_data->Jw_CopyStart 		= pos_data->JwIndex;
	pos_data->KeyAna_CopyStart 	= pos_data->KeyAnaIndex;
	pos_data->StsSec_CopyStart 	= pos_data->StsSec;
	pos_data->Ana_CopyStart 		= pos_data->AnaIndex;
	
	pos_data->JwTotCnt 			= 0;
	pos_data->KeyAnaTotFileCnt 	= 0;
	pos_data->StsTotSecCnt 		= 0;
	pos_data->AnaTotFileCnt 		= 0;
	
	pos_data->Jw_CopyInfoValid 		= 1;
	pos_data->KeyAna_CopyInfoValid 	= 1;
	pos_data->Sts_CopyInfoValid 		= 1;
	pos_data->Ana_CopyInfoValid 		= 1;
}
void JTC_SD_PosDataAdd(POS_DATA *pos_data, uint8_t addType,JTC_SD_STRUCTURE *jtcsd)
{
	if(addType & POS_DATA_ADDTYPE_POS)
	{
		pos_data->PosSec++;
		if (pos_data->PosSec >= jtcsd->PosSecOffset + (SD_POS_SEC_CNT >> 1))
			pos_data->PosSec = jtcsd->PosSecOffset;
	}
	
	if(addType & POS_DATA_ADDTYPE_JW)
	{			
		pos_data->JwIndex++;
		if (pos_data->JwIndex >= SD_JW_SEC_CNT)
			pos_data->JwIndex = 0;
		
		if (pos_data->JwTotCnt < SD_JW_SEC_CNT)
			pos_data->JwTotCnt++;
		else
			pos_data->Jw_CopyInfoValid = 0;
		
	}
	if(addType & POS_DATA_ADDTYPE_STS)
	{
		pos_data->StsSec++;
		if (pos_data->StsSec >= jtcsd->StsSecOffset + SD_STATUS_SEC_CNT)
			pos_data->StsSec = jtcsd->StsSecOffset;
		
		if (pos_data->StsTotSecCnt < SD_STATUS_SEC_CNT)
			pos_data->StsTotSecCnt++;
		else
			pos_data->Sts_CopyInfoValid = 0;
	}
	
	if(addType & POS_DATA_ADDTYPE_KEYANA)
	{
		pos_data->KeyAnaIndex++;
		if (pos_data->KeyAnaIndex >= KEY_SIG_FILE_CNT)
			pos_data->KeyAnaIndex = 0;
	
		if (pos_data->KeyAnaTotFileCnt < KEY_SIG_FILE_CNT)
			pos_data->KeyAnaTotFileCnt++;
		else
			pos_data->KeyAna_CopyInfoValid = 0;
	}
	
	if(addType & POS_DATA_ADDTYPE_ANA)
	{
		pos_data->AnaIndex++;
		if (pos_data->AnaIndex >= jtcsd->MaxSigFileNo)
			pos_data->AnaIndex = 0;

		if (pos_data->AnaTotFileCnt < jtcsd->MaxSigFileNo)
			pos_data->AnaTotFileCnt++;
		else
			pos_data->Ana_CopyInfoValid = 0;
	}
	return;
}


void JTC_SD_setPosData(POS_DATA *pos_data, uint8_t *writePtr)
{
	uint16_t i;
	uint8_t *p;
	
	p = (uint8_t*)pos_data;
	
	for (i = 0; i < sizeof(POS_DATA); i++){
	
		*p++ = writePtr[i];
	}
	return;
}

void JTC_SD_PosDataErrorRecovery(POS_DATA *pos_data,JTC_SD_STRUCTURE *jtcsd)
{
	if ((pos_data->KeyAnaIndex 		>= KEY_SIG_FILE_CNT) ||
		(pos_data->KeyAnaTotFileCnt	> KEY_SIG_FILE_CNT) ||
		(pos_data->KeyAna_CopyStart	>= KEY_SIG_FILE_CNT)){
				
		pos_data->KeyAnaIndex = 0;
		pos_data->KeyAnaTotFileCnt = 0;
		pos_data->KeyAna_CopyStart = 0;
		pos_data->KeyAna_CopyInfoValid = 0;
	}
	if ((pos_data->AnaIndex 		>= jtcsd->MaxSigFileNo) ||
		(pos_data->AnaTotFileCnt 	> jtcsd->MaxSigFileNo) ||
		(pos_data->Ana_CopyStart 	>= jtcsd->MaxSigFileNo)){
				
		pos_data->AnaIndex = 0;
		pos_data->AnaTotFileCnt = 0;
		pos_data->Ana_CopyStart = 0;
		pos_data->Ana_CopyInfoValid = 0;
	}
	if ((pos_data->StsSec >= jtcsd->KeySigSecOffset - ANALOG_FILE_SEC_CNT) ||
		(pos_data->StsSec < jtcsd->StsSecOffset))
		pos_data->StsSec = jtcsd->StsSecOffset;
	
	if (pos_data->StsTotSecCnt > SD_STATUS_SEC_CNT)
		pos_data->StsTotSecCnt = SD_STATUS_SEC_CNT;
	
	if ((pos_data->StsSec_CopyStart >= jtcsd->KeySigSecOffset - ANALOG_FILE_SEC_CNT) ||
		(pos_data->StsSec_CopyStart < jtcsd->StsSecOffset))
		FsramInfo.PosData.StsSec_CopyStart = jtcsd->StsSecOffset;
	
	return;
}
//----------------------------------------------------------------------------------
//-------------------------------Version--------------------------------------------
//----------------------------------------------------------------------------------

const uint8_t _SD_Version[] = {'V', 'e', 'r', '4', '0', '1', '0', '2'};
const uint8_t _SD_SubVer[] = {'4', '0', '0', '0'};

void JTC_SD_STRUCTURE_setVersionID(uint8_t *verStartAddr)
{
	*((uint32_t *)verStartAddr) = SD_VERSION_SECTOR_ID;
	
	return;
}
void JTC_SD_STRUCTURE_setVersionSVer(uint8_t *verStartAddr)
{
	uint8_t i;
	
	for (i = 0; i < 8; i++)
		verStartAddr[SD_VERSION_SECTOR_ADDR_sVER + i] = _SD_Version[i];
	
	return;
}
void JTC_SD_STRUCTURE_setVersionDate(uint8_t *verStartAddr, uint32_t time)
{
	*((uint32_t *)&(verStartAddr[SD_VERSION_SECTOR_ADDR_DATE])) = time;
	
	return;
}
void JTC_SD_STRUCTURE_setVersionJCH(uint8_t *verStartAddr, uint32_t jch)
{
	verStartAddr[SD_VERSION_SECTOR_ADDR_JCH + 0] = jch & 0xff;
	verStartAddr[SD_VERSION_SECTOR_ADDR_JCH + 1] = (jch & 0xff00) >> 8;
	verStartAddr[SD_VERSION_SECTOR_ADDR_JCH + 2] = (jch & 0xff0000) >> 16;
	verStartAddr[SD_VERSION_SECTOR_ADDR_JCH + 3] = jch >> 24;
	return;
}

uint32_t JTC_SD_STRUCTURE_getVersionJCH(uint8_t *verStartAddr)
{
	uint32_t jch = 0;
	jch <<= 8;
	jch += verStartAddr[SD_VERSION_SECTOR_ADDR_JCH + 3];
	jch <<= 8;
	jch += verStartAddr[SD_VERSION_SECTOR_ADDR_JCH + 2];
	jch <<= 8;
	jch += verStartAddr[SD_VERSION_SECTOR_ADDR_JCH + 1];
	jch <<= 8;
	jch += verStartAddr[SD_VERSION_SECTOR_ADDR_JCH + 0];
	return jch;
}


void JTC_SD_STRUCTURE_setVersionJCTYPE(uint8_t *verStartAddr, uint16_t jcType)
{
	verStartAddr[SD_VERSION_SECTOR_ADDR_JCTPYE + 0] = jcType & 0xff;
	verStartAddr[SD_VERSION_SECTOR_ADDR_JCTPYE + 1] = jcType >> 8;
	return;
}
uint16_t JTC_SD_STRUCTURE_getVersionJCTYPE(uint8_t *verStartAddr)
{
	uint16_t jcType = 0;
	
	jcType <<= 8;
	jcType += verStartAddr[SD_VERSION_SECTOR_ADDR_JCTPYE + 1];
	jcType <<= 8;
	jcType += verStartAddr[SD_VERSION_SECTOR_ADDR_JCTPYE + 0];
	return jcType;
}

void JTC_SD_STRUCTURE_setVersionCFID(uint8_t *verStartAddr, uint8_t *idBuf)
{
	uint8_t i;
	for (i = 0; i < 8; i++)
		verStartAddr[SD_VERSION_SECTOR_ADDR_CFID + i] = idBuf[i];
	return;
}

uint8_t JTC_SD_STRUCTURE_versionDataIsSame(uint8_t *verStartAddr,uint8_t *verData)
{
	uint16_t i;
	
	for (i = 0; i < JTC_VER_TOTAL_LEN; i++){
		
		if (verStartAddr[SD_VERSION_SECTOR_ADDR_bdVER + i] != verData[i]){
			
			if (verData[i] != 0xff)
				return 1;
		}
	}
	
	return 0;
}
void JTC_SD_STRUCTURE_setVersionCrc(uint8_t *verStartAddr)
{
	uint16_t crc;
	
	crc = Calc_CRCByte(verStartAddr, SD_VERSION_SECTOR_ADDR_CRC16);
	
	verStartAddr[SD_VERSION_SECTOR_ADDR_CRC16 + 0] = crc & 0xff;
	verStartAddr[SD_VERSION_SECTOR_ADDR_CRC16 + 1] = crc >> 8;
	return;
}
void JTC_SD_STRUCTURE_setVersionSWDATE(uint8_t *verStartAddr, 
										uint8_t mainV,
										uint8_t subV,
										uint8_t year,
										uint8_t month,
										uint8_t date)
{
	uint16_t i;
	
	i = year + 2000;
	
	verStartAddr[SD_VERSION_SECTOR_ADDR_SWDATE + 0] = mainV;
	verStartAddr[SD_VERSION_SECTOR_ADDR_SWDATE + 1] = subV;
	verStartAddr[SD_VERSION_SECTOR_ADDR_SWDATE + 2] = i >> 8;
	verStartAddr[SD_VERSION_SECTOR_ADDR_SWDATE + 3] = i & 0xff;
	verStartAddr[SD_VERSION_SECTOR_ADDR_SWDATE + 4] = month;
	verStartAddr[SD_VERSION_SECTOR_ADDR_SWDATE + 5] = date;
	
	return;
}
void JTC_SD_STRUCTURE_setVersionEXsVER(uint8_t *verStartAddr)
{
	verStartAddr[SD_VERSION_SECTOR_ADDR_EXsVER + 0] = _SD_SubVer[0];
	verStartAddr[SD_VERSION_SECTOR_ADDR_EXsVER + 1] = _SD_SubVer[1];
	verStartAddr[SD_VERSION_SECTOR_ADDR_EXsVER + 2] = _SD_SubVer[2];
	verStartAddr[SD_VERSION_SECTOR_ADDR_EXsVER + 3] = _SD_SubVer[3];
	return;
}
//--------------
uint8_t JTC_SD_STRUCTURE_checkVersion(uint8_t *verStartAddr)
{
	uint16_t crc;
	uint8_t i;
	
	if (*(uint32_t *)verStartAddr != SD_VERSION_SECTOR_ID)
		return 1;
	
	for (i = 0; i < 8; i++)
	{		
		if (verStartAddr[4 + i] != _SD_Version[i])
		{
			return 1;
		}
	}
	crc = Calc_CRCByte(verStartAddr, SD_VERSION_SECTOR_ADDR_CRC16);
	if (crc != (*(uint16_t *)&(verStartAddr[SD_VERSION_SECTOR_ADDR_CRC16])))
		return 1;
					
	return 0;
}
//---------------------------------------------------------------------------



void JTC_SD_STRUCTURE_setStr(	uint32_t totalSecs,
								uint32_t firstSec,
								uint16_t clusterSec, 
								uint8_t sw, 
								JTC_SD_STRUCTURE *sdStr)
{
	sdStr->VersSecOffset = firstSec + clusterSec + SD_RSVDSEC_CNT_FIRST;
	sdStr->JwSecOffset = sdStr->VersSecOffset + SD_VERSION_SEC_CNT;
	sdStr->PosSecOffset = sdStr->JwSecOffset + SD_JW_SEC_CNT + SD_RSVD_SEC_CNT;
	sdStr->StsSecOffset = sdStr->PosSecOffset + SD_POS_SEC_CNT + SD_TEST_SEC_CNT + SD_RSVD_SEC_CNT_LAST;
	sdStr->KeySigSecOffset = sdStr->StsSecOffset + SD_STATUS_SEC_CNT + ANALOG_FILE_SEC_CNT;
	sdStr->SigSecOffset = sdStr->KeySigSecOffset + KEY_SIG_FILE_CNT * ANALOG_FILE_SEC_CNT + ANALOG_FILE_SEC_CNT;
	sdStr->MaxSigFileNo = (totalSecs - 1 - JTC_sdStr.SigSecOffset) / ANALOG_FILE_SEC_CNT - 1;
	
	if ((sw & 0x02))
		JTC_sdStr.MaxSigFileNo = (JTC_sdStr.MaxSigFileNo > LIMIT_ANALOG_FILE_COUNT)?LIMIT_ANALOG_FILE_COUNT:JTC_sdStr.MaxSigFileNo;
	
	if (sdStr->MaxSigFileNo > LIMIT_ANALOG_FILE_COUNT * 2)
		sdStr->MaxSigFileNo = LIMIT_ANALOG_FILE_COUNT * 2;
	
	return;
}


//---------------------------------------------------------------------------
///EOF
